package com.ysstech.reportworld.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.spring.PropertyPreFilters;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.ysstech.common.cache.RedisCacheManager;
import com.ysstech.common.entity.TreeNode;
import com.ysstech.common.exception.BusinessException;
import com.ysstech.common.service.DicvalueService;
import com.ysstech.common.util.DateUtil;
import com.ysstech.reportworld.entity.DataModular;
import com.ysstech.reportworld.entity.Modular;
import com.ysstech.reportworld.enums.ReportWorldEnum;
import com.ysstech.reportworld.enums.ReportWorldStatusEnum;
import com.ysstech.reportworld.mapper.DataModularMapper;
import com.ysstech.reportworld.mapper.ModularMapper;
import com.ysstech.reportworld.service.ModularService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 报表世界模块表 服务实现类
 * </p>
 *
 * @author lishuangliang
 * @since 2022-04-28
 */
@Service
public class ModularServiceImpl extends ServiceImpl<ModularMapper, Modular> implements ModularService {

    @Autowired
    private DataModularMapper dataModularMapper;
    @Autowired
    private DicvalueService dicvalueService;
    @Autowired
    private RedisCacheManager redisCacheManager;

    /**
     * 查询报表模块树信息
     *
     * @return
     */
    public List<TreeNode> queryModularTree() throws Exception {
        List<TreeNode> list = new ArrayList<>();
        QueryWrapper<Modular> wrapper = new QueryWrapper<>();
        wrapper.orderByAsc("NAME");
        List<Modular> listModular = this.list(wrapper);
        if (CollectionUtils.isEmpty(listModular)) {
            return list;
        }
        list.addAll(this.recursionTree("0", listModular));
        return list;
    }

    private List<TreeNode> recursionTree(String id, List<Modular> listModular) throws Exception {
        List<TreeNode> list = new ArrayList<>();
        for (Modular reportModular : listModular) {
            if (!id.equals(reportModular.getParentId())) {
                continue;
            }
            TreeNode treeNode = this.reportModularToNode(reportModular);
            List<TreeNode> children = recursionTree(reportModular.getId(), listModular);
            if (null == children || children.size() == 0) {
                treeNode.setState("open");
            } else {
                treeNode.setChildren(children);
            }
            list.add(treeNode);
        }
        return list;
    }

    /**
     * 将业务功能转化成TreeNode
     */
    private TreeNode reportModularToNode(Modular reportModular) {
        TreeNode node = new TreeNode();
        node.setId(reportModular.getId());
        node.setText(reportModular.getName());
        node.setState("closed");
        node.setChecked(false);
        node.setIconCls("icon-bricks");
        node.setPId(reportModular.getParentId());
        node.setTitle(reportModular.getName());
        return node;
    }

    /**
     * 里获取报表模块信息
     *
     * @return
     * @throws Exception
     */
    public Map<String, Modular> getModularMap() throws Exception {
        Map<String, Modular> mapReportModular = new HashMap<>();
        QueryWrapper<Modular> wrapper = new QueryWrapper<>();
        wrapper.orderByAsc("NAME");
        List<Modular> listModular = this.list(wrapper);
        if (CollectionUtils.isEmpty(listModular)) {
            return null;
        }
        for (Modular modular : listModular) {
            if (null == modular || StringUtils.isBlank(modular.getId())) {
                continue;
            }
            mapReportModular.put(modular.getId(), modular);
        }
        return mapReportModular;
    }


    /**
     * 查询所有下级模块的模块集合
     *
     * @param id 模块编号
     * @return
     * @throws Exception
     */
    public List<Modular> queryListModular(String id) throws Exception {
        if (StringUtils.isBlank(id)) {
            throw new BusinessException("获取模块信息失败，请稍后重试！");
        }
        List<String> list = this.queryModularIds(id);
        QueryWrapper<Modular> wrapper = new QueryWrapper<>();
        wrapper.in("ID", list);
        List<Modular> listModular = this.list(wrapper);
        return listModular;
    }

    /**
     * 查询所有下级模块的模块id集合
     *
     * @param id
     * @return
     * @throws Exception
     */
    public List<String> queryModularIds(String id) throws Exception {
        if (StringUtils.isBlank(id)) {
            throw new BusinessException("获取模块信息失败，请稍后重试！");
        }
        List<String> strList = new ArrayList<>();
        strList.add(id);
        QueryWrapper<Modular> wrapper = new QueryWrapper<>();
        wrapper.orderByAsc("NAME");
        List<Modular> list = this.list(wrapper);
        recursionIds(id, strList, list);
        return strList;
    }

    private void recursionIds(String id, List<String> strList, List<Modular> list) {
        for (Modular reportModular : list) {
            if (!id.equals(reportModular.getParentId())) {
                continue;
            }
            strList.add(reportModular.getId());
            recursionIds(reportModular.getId(), strList, list);
        }
    }

    /**
     * 添加模块信息
     *
     * @param modular
     * @throws Exception
     */
    public void addModular(Modular modular) throws Exception {
        if (modular == null) {
            throw new BusinessException("获取模块信息失败，请稍后重试！");
        }
        String id = DateUtil.generateUUID();
        modular.setId(id);
        modular.setStatus(ReportWorldStatusEnum.REPORT_NORMAL.getCode());
        modular.setAddUser(redisCacheManager.getLoginUserInfo().getLoginId());
        modular.setAddTime(LocalDateTime.now());
        if ("0".equals(modular.getParentId())) {
            this.save(modular);
            return;
        }
        //添加之前没有下级模块的数据的 添加了以后 模块的关联关系修改到下级
        // 获取该模块的上级之前是不是最明细的
        QueryWrapper<Modular> wrapper = new QueryWrapper<>();
        wrapper.eq("PARENT_ID", modular.getParentId());
        List<Modular> list = this.list(wrapper);
        if (CollectionUtils.isEmpty(list)) { //添加的上级以前没有下级
            // 将关联关系表中原来模块的数据，更新成现在这个新的下级菜单
            UpdateWrapper<DataModular> updateWrapper = new UpdateWrapper<>();
            updateWrapper.eq("MODULAR_ID", modular.getParentId());
            DataModular dataModular = new DataModular();
            dataModular.setModularId(id);
            dataModular.setStatus(ReportWorldStatusEnum.REPORT_NORMAL.getCode());
            dataModular.setAddUser(redisCacheManager.getLoginUserInfo().getLoginId());
            dataModular.setAddTime(LocalDateTime.now());
            dataModularMapper.update(dataModular, updateWrapper);
        }
        this.save(modular);
    }

    /**
     * 修改模块信息
     *
     * @param modular
     * @throws Exception
     */
    public void editModular(Modular modular) throws Exception {
        if (modular == null || StringUtils.isBlank(modular.getId())) {
            throw new BusinessException("获取模块信息失败，请稍后重试！");
        }
        // 修改之前的上级只有一个下级
        Modular oldModular = this.getById(modular.getId());
        QueryWrapper<Modular> wrapperOld = new QueryWrapper<>();
        wrapperOld.eq("PARENT_ID", oldModular.getId());
        List<Modular> listOld = this.list(wrapperOld);
        if (CollectionUtils.isEmpty(listOld)) { //修改之前没有下级
            QueryWrapper<Modular> wrapper = new QueryWrapper<>();
            wrapper.eq("PARENT_ID", oldModular.getParentId());
            List<Modular> list = this.list(wrapper);
            if (!CollectionUtils.isEmpty(list) && list.size() == 1) {
                // 原来的关联表是这个明细的ID 更新成现在将会变成明细的上级ID
                UpdateWrapper<DataModular> updateWrapper = new UpdateWrapper<>();
                updateWrapper.eq("MODULAR_ID", oldModular.getId());
                DataModular dataModular = new DataModular();
                dataModular.setModularId(oldModular.getParentId());
                dataModular.setStatus(ReportWorldStatusEnum.REPORT_NORMAL.getCode());
                dataModular.setAddUser(redisCacheManager.getLoginUserInfo().getLoginId());
                dataModular.setAddTime(LocalDateTime.now());
                dataModularMapper.update(dataModular, updateWrapper);
            }
        }
        modular.setEditUser(redisCacheManager.getLoginUserInfo().getLoginId());
        modular.setEditTime(LocalDateTime.now());
        //修改后的上级
        if ("0".equals(modular.getParentId())) {
            this.updateById(modular);
            return;
        }
        // 修改后的这上级 之前是否存在下级
        QueryWrapper<Modular> wrapper = new QueryWrapper<>();
        wrapper.eq("PARENT_ID", modular.getParentId());
        List<Modular> list = this.list(wrapper);
        if (CollectionUtils.isEmpty(list)) { //添加的上级以前没有下级
            // 将关联关系表中原来模块的数据，更新成现在这个新的下级菜单
            UpdateWrapper<DataModular> updateWrapper = new UpdateWrapper<>();
            updateWrapper.eq("MODULAR_ID", modular.getParentId());
            DataModular dataModular = new DataModular();
            dataModular.setModularId(modular.getId());
            dataModular.setStatus(ReportWorldStatusEnum.REPORT_NORMAL.getCode());
            dataModular.setAddUser(redisCacheManager.getLoginUserInfo().getLoginId());
            dataModular.setAddTime(LocalDateTime.now());
            dataModularMapper.update(dataModular, updateWrapper);
        }
        this.updateById(modular);
    }

    /**
     * 删除模块信息
     *
     * @param id
     * @throws Exception
     */
    public void delModular(String id) throws Exception {
        if (StringUtils.isBlank(id)) {
            throw new BusinessException("获取删除模块信息失败，请稍后重试！");
        }
        List<String> list = this.queryModularIds(id); //所有下级模块
        Modular oldModular = this.getById(id);
        // 删除的这个ID 不是一个一级的
        if ("0".equals(oldModular.getParentId())) {
            // 删除关联关系表中所所有改id包括所有下级的
            QueryWrapper<DataModular> wrapper = new QueryWrapper<>();
            wrapper.in("MODULAR_ID", list);
            dataModularMapper.delete(wrapper);
            this.removeByIds(list);
            return;
        }
        UpdateWrapper<DataModular> updateWrapper = new UpdateWrapper<>();
        updateWrapper.in("MODULAR_ID", list);
        DataModular dataModular = new DataModular();
        dataModular.setModularId(oldModular.getParentId());
        dataModular.setStatus(ReportWorldStatusEnum.REPORT_NORMAL.getCode());
        dataModular.setAddUser(redisCacheManager.getLoginUserInfo().getLoginId());
        dataModular.setAddTime(LocalDateTime.now());
        dataModularMapper.update(dataModular, updateWrapper);
        this.removeByIds(list);
    }

    /**
     * 获取模块对应表信息
     *
     * @return
     */
    @Override
    public List<DataModular> getTableInfo(DataModular dataModular) throws Exception {
        if (null == dataModular || StringUtils.isBlank(dataModular.getModularId())) {
            throw new BusinessException("获取模块对应表信息失败，请稍后重试！");
        }
        List<DataModular> list = dataModularMapper.getTableInfo(dataModular);
        if (CollectionUtils.isEmpty(list)) {
            return null;
        }
        // 报表世界所在分层
        Map<String, String> mapTableLayered = dicvalueService.getCacheDicValueMap(ReportWorldEnum.REPORT_TABLE_LAYERED.getCode());
        // 表类型
        Map<String, String> mapFtype = dicvalueService.getCacheDicValueMap(ReportWorldEnum.REPORT_TABLE_FTYPE.getCode());
        // 表来源
        Map<String, String> maptFsource = dicvalueService.getCacheDicValueMap(ReportWorldEnum.REPORT_TABLE_FSOURCE.getCode());
        for (DataModular modular : list) {
            if (null == modular) {
                continue;
            }
            //报表世界所在分层
            if (null != mapTableLayered && mapTableLayered.containsKey(String.valueOf(modular.getLayered()))) {
                modular.setLayered(mapTableLayered.get(String.valueOf(modular.getLayered())));
            }
            //表类型
            if (null != mapFtype && mapFtype.containsKey(String.valueOf(modular.getFtype()))) {
                modular.setFtype(mapFtype.get(String.valueOf(modular.getFtype())));
            }
            //表来源
            if (null != maptFsource && maptFsource.containsKey(String.valueOf(modular.getFsource()))) {
                modular.setFsource(maptFsource.get(String.valueOf(modular.getFsource())));
            }
        }
        return list;
    }

    /**
     * 模块数据的json
     */
    public String getModularJsonInfo() throws Exception {
        String[] includeProperties = {"id", "parentId", "name", "status"};
        PropertyPreFilters filters = new PropertyPreFilters();
        PropertyPreFilters.MySimplePropertyPreFilter includefilter = filters.addFilter();
        includefilter.addIncludes(includeProperties);
        QueryWrapper<Modular> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("STATUS", ReportWorldStatusEnum.getUpgradeToolsZipStatus());
        queryWrapper.orderByAsc("NAME");
        List<Modular> list = this.list(queryWrapper);
        return JSONObject.toJSONString(list, includefilter, SerializerFeature.WriteMapNullValue);
    }

}
